package lzy.impl.smallspring.beans.factory.support;

import lzy.impl.smallspring.beans.BeansException;
import lzy.impl.smallspring.beans.factory.BeanFactory;
import lzy.impl.smallspring.beans.factory.config.BeanDefinition;
import lzy.impl.smallspring.beans.factory.config.BeanPostProcessor;

import java.util.*;

/**
 * 定义了getBean的抽象方法：如果有单例就拿，如果没有有就创建单例拿
 * 但是此处没有处理非单例bean的情况，后续需要处理
 */
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {

    private final Set<BeanPostProcessor> beanPostProcessors = new HashSet<>();

    @Override
    public Object getBean(String name) throws BeansException {
        return doGetBean(name);
    }


    @Override
    public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
        // FIXME： 添加对Type的Aware
        return (T) doGetBean(name);
    }

    @Override
    public Object getBean(String name, Object... args) throws BeansException {
        return doGetBean(name, args);
    }

    protected <T> T doGetBean(String name, final Object... args) throws BeansException {
        T bean = (T) getSingleton(name);
        if (bean != null) {
            return bean;
        }
        BeanDefinition beanDefinition = getBeanDefinition(name);
        return (T) createAndAddSingletonBean(name, beanDefinition, args);
    }


    protected abstract BeanDefinition getBeanDefinition(String name) throws BeansException;


    protected abstract Object createAndAddSingletonBean(String beanName, BeanDefinition definition, Object[] args) throws BeansException;


    public void addBeanPostProcessors(BeanPostProcessor... beanPostProcessors) {
        this.beanPostProcessors.addAll(Arrays.asList(beanPostProcessors));
    }

    public List<BeanPostProcessor> getBeanPostProcessors() {
        return new ArrayList<>(beanPostProcessors);
    }
}
